package calvin.study.rabbitmq.service.impl;

import java.io.IOException;
import java.util.Map;

import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Service;

import com.rabbitmq.client.Channel;

/**
 * 监听死信队列，消费死信
 * @author wh
 *
 */
@Service
public class DeadLetterService {

	
	//bindings其实就是用来确定队列和交换机绑定关系
	@RabbitListener(bindings =@QueueBinding(
	   // email.fanout.queue 是队列名字，这个名字你可以自定随便定义。
	   value = @Queue(value = "dead_letter_queue1",autoDelete = "false"),
	   // order.fanout 交换机的名字 必须和生产者保持一致
	   exchange = @Exchange(value = "dead_letter_direct_exchange",
	           // 这里是确定的rabbitmq模式是：fanout 是以广播模式 、 发布订阅模式
	           type = ExchangeTypes.DIRECT)
			)
	)
	@RabbitHandler
	public void consumeDeadLetter(@Payload String  payload, @Headers Map<String, Object> headers, Channel channel) throws Exception {
			   Long deliveryTag = null;
			   boolean multiple = false;
			   System.out.println("========死信队列=======");
			try {
				// 此处省略发邮件的逻辑
		        System.out.println("consume dead letter-------------->" + payload);
		        deliveryTag  = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);

		        //手工ACK,确认一条消息已经被消费
		        channel.basicAck(deliveryTag,multiple);
			} catch (Exception e) {
				try {
					channel.basicNack(deliveryTag, multiple, false);
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		
	}

}
